#include "AbstractChannel.h"
#include "../eventloop.h"
#include "../event_manager.h"
#include "tinyrpc/base/logger/logger.h"
namespace TinyRPC{

AbstractChannel::AbstractChannel(int fd)
: m_fd(std::make_shared<Fd>(fd)){
    
    m_event = std::make_shared<Event>(fd, this);
    EventManager::GetInstance().addEventPtr(m_event);
    // m_event->enableReading();
    // m_event->setReadTask(Task(std::bind(&WakeupChannel::read, this), false));
}

AbstractChannel::~AbstractChannel(){
    deleteEvent(EventLoop::CurrentEventLoop());
    EventManager::GetInstance().delEventPtr(m_fd->fd());
}

void AbstractChannel::modifyEvent(EventLoop * ownerLoop){
    if(m_event->getStatus() == EventStatus::ADDED && ownerLoop){
        ownerLoop->modifyEvent(m_event);
        LOG_INFO<<"modify event in epoll, fd:"<<m_event->getFd()<<" new event: "<<m_event->getEventOP();
    }
}
void AbstractChannel::deleteEvent(EventLoop * ownerLoop){
    m_event->enableNone();
    if(m_event->getStatus() == EventStatus::ADDED && ownerLoop){
        ownerLoop->deleteEvent(m_event);
        LOG_INFO<<"delete event in epoll, fd:"<<m_event->getFd();
        m_event->setStatus(EventStatus::DELETED);
    }
}
void AbstractChannel::addEvent(EventLoop * ownerLoop){
    if((m_event->getStatus() == EventStatus::INTIED || m_event->getStatus()== EventStatus::DELETED ) && ownerLoop){
        ownerLoop->addEvent(m_event);
        LOG_INFO<<"add event in epoll, fd:"<<m_event->getFd()<<" new event: "<<m_event->getEventOP();
        m_event->setStatus(EventStatus::ADDED);
    }
}

// 既可以是 添加 修改 删除
void AbstractChannel::updateEvent(int interestOp, const Task& task, EventLoop * ownerLoop){

    // 已经添加过了 并且这次关注的事情和之前相同， 则不需要修改了epoll 红黑树了
    // 只需要重新设置一下readTask 
    if((m_event->getStatus() == EventStatus::ADDED)&&(m_event->getEventOP() == interestOp)){
        if(interestOp == ReadEvent) {
            m_event->setReadTask(task);
        }else if(interestOp == WriteEvent){
            m_event->setWriteTask(task);
        }
        return;
    }

    m_event->enableNone();
    if(interestOp == ReadEvent) {
        m_event->enableReading();
        m_event->setReadTask(task);
    }else if(interestOp == WriteEvent){
        m_event->enableWriting();
        m_event->setWriteTask(task);
    }

    // 还没有被添加 或者删除时 , 需要添加
    if(m_event->getStatus() == EventStatus::INTIED || m_event->getStatus()== EventStatus::DELETED && interestOp != NoneEvent){
        addEvent(ownerLoop);
    }
    
    else if(m_event->getStatus() == EventStatus::ADDED && interestOp != NoneEvent){
        modifyEvent(ownerLoop);
    }
    
    else if(m_event->getStatus() == EventStatus::ADDED && interestOp == NoneEvent){
        deleteEvent(ownerLoop);
    }
}
}
